package com.qf.electronic.mall.cart.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.qf.cart.api.ICartService;
import com.qf.constant.CartConstant;
import com.qf.constant.RedisConstant;
import com.qf.dto.ResultBean;
import com.qf.dto.TProductCartDTO;
import com.qf.entity.TProduct;
import com.qf.mapper.TProductMapper;
import com.qf.util.StringUtils;
import com.qf.vo.CartItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
@Service
public class CartServiceImpl implements ICartService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private TProductMapper productMapper;
    @Override
    public ResultBean addProduct(String uuid, Long productId, int count) {
        String redisKey = StringUtils.getRedisKey(RedisConstant.USER_CART_PRE, uuid);
        Object obj = redisTemplate.opsForValue().get(redisKey);

        if (obj == null) {
            CartItem cartItem = new CartItem();
            cartItem.setProductId(productId);
            cartItem.setCount(count);
            cartItem.setUpdateTime(new Date());

            List<CartItem> carts=new ArrayList<>();
            carts.add(cartItem);
            redisTemplate.opsForValue().set(redisKey,carts);
            return ResultBean.success(carts,CartConstant.CART_ADD_SUCCESS_MSG);
        }
        List<CartItem> carts=new ArrayList<>();
        for (CartItem cartItem : carts) {
            if (cartItem.getProductId().longValue()==productId.longValue()){
                cartItem.setCount(cartItem.getCount()+count);
                cartItem.setUpdateTime(new Date());
                redisTemplate.opsForValue().set(redisKey,carts);
                return ResultBean.success(carts,CartConstant.CART_ADD_SUCCESS_MSG);
            }
        }
        CartItem cartItem = new CartItem();
        cartItem.setProductId(productId);
        cartItem.setCount(count);
        cartItem.setUpdateTime(new Date());
        carts.add(cartItem);
        redisTemplate.opsForValue().set(redisKey,carts);
        return ResultBean.success(carts,CartConstant.CART_ADD_SUCCESS_MSG);
    }

    @Override
    public ResultBean cleanCart(String uuid) {
        String redisKey = StringUtils.getRedisKey(RedisConstant.USER_CART_PRE, uuid);
        redisTemplate.delete(redisKey);
        return ResultBean.success(CartConstant.CART_CLEAN_SUCCESS_MSG);
    }

    @Override
    public ResultBean updateCart(String uuid, Long productId, int count) {
        if(uuid!=null && !"".equals(uuid)){
            String redisKey = StringUtils.getRedisKey(RedisConstant.USER_CART_PRE, uuid);
            Object obj = redisTemplate.opsForValue().get(redisKey);
            if (obj != null) {
                List<CartItem> carts=new ArrayList<>();
                for (CartItem cartItem : carts) {
                    if (cartItem.getProductId().longValue()==productId.longValue()){
                        cartItem.setCount(count);
                        cartItem.setUpdateTime(new Date());
                        redisTemplate.opsForValue().set(redisKey,carts);
                        return ResultBean.success(carts,CartConstant.CART_UPDATE_SUCCESS_MSG);
                    }
                }
            }
        }
        return ResultBean.error(CartConstant.CART_NULL_MSG);
    }

    @Override
    public ResultBean showCart(String id) {
        if (id!=null && !"".equals(id)){
            String redisKey = StringUtils.getRedisKey(RedisConstant.USER_CART_PRE, id);
            Object obj = redisTemplate.opsForValue().get(redisKey);
            if (obj != null) {
                List<CartItem> carts= (List<CartItem>) obj;
                List<TProductCartDTO> products=new ArrayList<>();
                for (CartItem cartItem : carts) {
                    String productKey = StringUtils.getRedisKey(RedisConstant.PRODUCT_PRE, cartItem.getProductId().toString());
                    TProduct product= (TProduct) redisTemplate.opsForValue().get(productKey);
                    if (product == null) {
                        product=productMapper.selectByPrimaryKey(cartItem.getProductId());
                        redisTemplate.opsForValue().set(productKey,product);
                    }
                    TProductCartDTO cartDTO = new TProductCartDTO();
                    cartDTO.setProduct(product);
                    cartDTO.setCount(cartItem.getCount());
                    cartDTO.setUpdateTime(cartItem.getUpdateTime());
                    products.add(cartDTO);
                }
                Collections.sort(products, new Comparator<TProductCartDTO>() {
                    @Override
                    public int compare(TProductCartDTO o1, TProductCartDTO o2) {
                        return (int) (o1.getUpdateTime().getTime()-o2.getUpdateTime().getTime());
                    }
                });
                return ResultBean.success(products);
            }
        }
        return ResultBean.error(CartConstant.CART_NULL_MSG);
    }

    @Override
    public ResultBean mergeCart(String uuid, String userId) {
        String notLoginRedisKey = StringUtils.getRedisKey(RedisConstant.USER_CART_PRE, uuid);
        String loginRedisKey = StringUtils.getRedisKey(RedisConstant.USER_CART_PRE, userId);
        Object notLoginObj = redisTemplate.opsForValue().get(notLoginRedisKey);
        Object longinObj = redisTemplate.opsForValue().get(loginRedisKey);
        if (notLoginObj == null) {
            return ResultBean.success(CartConstant.CART_MERGE_NOTLOGIN_MSG);
        }
        if (longinObj == null) {
            redisTemplate.opsForValue().set(loginRedisKey,notLoginObj);
            redisTemplate.delete(notLoginRedisKey);
            return ResultBean.success(notLoginObj,CartConstant.CART_MERGE_SUCCESS_MSG);
        }
        List<CartItem> notLoginCarts= (List<CartItem>) notLoginObj;
        List<CartItem> loginCarts= (List<CartItem>) longinObj;
        Map<Long,CartItem> map=new HashMap<>();
        for (CartItem notLoginCartItem : notLoginCarts) {
            map.put(notLoginCartItem.getProductId(),notLoginCartItem);
        }

        for (CartItem loginCartItem : loginCarts) {
            CartItem currentCartItem = map.get(loginCartItem.getProductId());
            if (currentCartItem != null) {
                currentCartItem.setCount(currentCartItem.getCount()+loginCartItem.getCount());
            }else {
                map.put(loginCartItem.getProductId(),loginCartItem);
            }
        }

        redisTemplate.delete(notLoginRedisKey);
        Collection<CartItem> values = map.values();
        List<CartItem> newCarts=new ArrayList<>(values);
        redisTemplate.opsForValue().set(loginRedisKey,newCarts);
        return ResultBean.success(newCarts,CartConstant.CART_MERGE_SUCCESS_MSG);
    }
}
